package Client;

import General.*;

import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Vector;

public class Main {

	public static void printAllServices(String address, int port) throws RemoteException, NotBoundException {
		System.out.println("[CLIENT] All services:");		
		Registry registry = LocateRegistry.getRegistry(address, port);
		Registry registryImplementation = (Registry)registry.lookup("RegistryImplementation");
		String[] list = registryImplementation.list();
		for (String s : list) {
			System.out.println("- " + s);
		}
	}
	
	public static void printReflectionInfo(Object o) {
		System.out.println("");
		System.out.println("[CLIENT] Implemented interfaces for " + o.getClass().getName() + ":");
		Class[] theInterfaces = o.getClass().getInterfaces();
	    for (int i = 0; i < theInterfaces.length; i++) {
	      String interfaceName = theInterfaces[i].getName();
	      System.out.println("- " + interfaceName);
	    }
	}
	
	public static void main(String[] args) {
		try {
			//System.setProperty("java.rmi.server.codebase", "http://localhost:8080/");
			//System.setProperty("java.security.policy", "Policies/client.policy");
	        //System.setProperty("javax.net.ssl.trustStore", "Policies/ClientTrustStore");
	        //System.setProperty("javax.net.ssl.keyStore", "Policies/ClientKeyStore");
	        //System.setProperty("javax.net.ssl.keyStorePassword", "nieldeckx");
	        
			if(System.getSecurityManager() == null) {
				System.setSecurityManager(new RMISecurityManager());
			}

	        String address = "localhost";
	        int port = 1099;
	        
	        if (args.length > 0)
	        	address = args[0];
	        if (args.length > 1)
	        	port =  Integer.valueOf(args[1]);
	        
			Registry registry = LocateRegistry.getRegistry(address, port);
			Registry registryImplementation = (Registry)registry.lookup("RegistryImplementation");
			ProxyInterface proxyInterface = (ProxyInterface) registryImplementation.lookup("ClientProxy");
			
			printAllServices(address, port);
			printReflectionInfo(proxyInterface);
						
			System.out.println("");			
			System.out.println("[CLIENT] Creating products.");
			Product product1 = new Product("Macbook", 50, false, Product.AIR);
			Product product2 = new Product("Fosfor", 40, true, Product.AIR_PRIORITY);
			Product product3 = new Product("Apple TV", 20, false, Product.GROUND);
			Product product4 = new Product("iPhone", 10, false, Product.AIR_PRIORITY);
			Product product5 = new Product("iMac", 30, false, Product.AIR);
			
			System.out.println("");
			System.out.println("[CLIENT] Get quote.");
			Address a = new Address("Belgium", "Middelheimlaan", 1);
			long timeBefore = System.currentTimeMillis();
			QuoteInterface quote = proxyInterface.quote(product1, a, a);
			System.out.println("Quote round trip: " + (System.currentTimeMillis()-timeBefore)  + "ms");
			System.out.println("Price when shipping " + product1.getName() + ": " + quote.getPrice());
			
			timeBefore = System.currentTimeMillis();
			quote = proxyInterface.quote(product2, a, a);
			System.out.println("Quote round trip: " + (System.currentTimeMillis()-timeBefore)  + "ms");
			System.out.println("Price when shipping " + product2.getName() + ": " + quote.getPrice());
			
			timeBefore = System.currentTimeMillis();
			quote = proxyInterface.quote(product3, a, a);
			System.out.println("Quote round trip: " + (System.currentTimeMillis()-timeBefore)  + "ms");
			System.out.println("Price when shipping " + product3.getName() + ": " + quote.getPrice());
			
			System.out.println("");
			System.out.println("[CLIENT] Administrator changed rates.");
			proxyInterface.changeRates(30, 60, 80);
			
			System.out.println("");
			System.out.println("[CLIENT] Get quote.");
			quote = proxyInterface.quote(product1, a, a);
			System.out.println("Price when shipping " + product1.getName() + ": " + quote.getPrice());
			
			quote = proxyInterface.quote(product2, a, a);
			System.out.println("Price when shipping " + product2.getName() + ": " + quote.getPrice());
			
			quote = proxyInterface.quote(product3, a, a);
			System.out.println("Price when shipping " + product3.getName() + ": " + quote.getPrice());
			
			System.out.println("");
			System.out.println("[CLIENT] Request for shipment.");
			CallbackImplementation callback = new CallbackImplementation();
			EventInterface event = new EventImplementation(callback);
			System.out.println("Request for " + product1.getName() + " accepted: " + proxyInterface.request(product1, event));	
			Thread.sleep(1000);
			System.out.println("Request for " + product2.getName() + " accepted: " + proxyInterface.request(product2, event));			
			System.out.println("Request for " + product3.getName() + " accepted: " + proxyInterface.request(product3, event));	
			Thread.sleep(1000);
			System.out.println("Request for " + product4.getName() + " accepted: " + proxyInterface.request(product4, event));			
			System.out.println("Request for " + product5.getName() + " accepted: " + proxyInterface.request(product5, event));			

			
			System.out.println("");
			System.out.println("[CLIENT] Get status.");
			System.out.println("Status of " + product1.getName() + ": " + proxyInterface.status(product1));
			System.out.println("Status of " + product2.getName() + ": " + proxyInterface.status(product2));
			System.out.println("Status of " + product3.getName() + ": " + proxyInterface.status(product3));
			System.out.println("Status of " + product4.getName() + ": " + proxyInterface.status(product4));
			System.out.println("Status of " + product5.getName() + ": " + proxyInterface.status(product5));
			
			System.out.println("");
			System.out.println("[CLIENT] Pending shipments.");
			timeBefore = System.currentTimeMillis();
			Vector<Product> pending = proxyInterface.pendingShipments();
			for (Product product : pending) {
				System.out.println("- " + product.getName());
			}
			
			System.out.println("");
			System.out.println("[CLIENT] Wait 3 second.");
			Thread.sleep(3000);
			
			System.out.println("");
			System.out.println("[CLIENT] Complete shipments.");
			ProductIterator productIterator = new ProductIterator(proxyInterface);
			Product pr = productIterator.next();
			while (pr != null) {
				System.out.println("- " + pr.getName());
				pr = productIterator.next();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}